#include "../head/client.h"

int main(int argc, char *argv[])
{
	// 可执行程序 服务端IP 服务端端口
	// ARGS_CHECK(argc, 3);

	// 从配置文件中加载服务器ip
	char ip[100];
	bzero(ip, sizeof(ip));
	getparameter("ip", ip); // getparameter.c
	printf("ip: %s\n", ip);
	// 从配置文件中加载服务器端口
	char port[100];
	bzero(port, sizeof(port));
	getparameter("port", port); // getparameter.c
	printf("port: %s\n", port);

	int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
	ERROR_CHECK(socket_fd, -1, "socket");
	if (socket_fd == -1)
	{
		NETDISK_LOG_ERR("short socket");
	}

	struct sockaddr_in serverAddr;
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = htons(atoi(port));
	serverAddr.sin_addr.s_addr = inet_addr(ip);
	int res_conn = connect(socket_fd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
	ERROR_CHECK(res_conn, -1, "connect");
	NETDISK_LOG_INFO_1(socket_fd, "1 client connected", serverAddr);
	if (res_conn == -1)
	{
		NETDISK_LOG_ERR("short connect");
	}

	// 发送连接类型（short）
	train_t train;
	bzero(&train, sizeof(train));
	train.length = strlen("short");
	memcpy(train.data, "short", train.length);
	send(socket_fd, &train, sizeof(train.length) + train.length, MSG_NOSIGNAL);

	printf("在使用网盘服务前需要验证您的身份：\n");
	printf("请选择注册或登录(输入数字即可)：1.注册\t2.登录\n");
	int opt = 0;
	scanf("%d", &opt);
	getchar(); // 读回车

	char token[1024] = {0};
	char username[1024] = {0};
	while (1)
	{
		bzero(&train, sizeof(train));
		bzero(token, sizeof(token));
		bzero(username, sizeof(username));

		if (opt == 1) // 注册
		{
			user_register(socket_fd, username); // user.c
			// 获得服务器返回的jwt加密的token
			recv(socket_fd, &train.length, sizeof(train.length), MSG_WAITALL);
			recv(socket_fd, train.data, train.length, MSG_WAITALL);
			memcpy(token, train.data, train.length);
			break;
		}
		else if (opt == 2) // 登录
		{
			user_login(socket_fd, username); // user.c
			// 获得服务器返回的jwt加密的token
			recv(socket_fd, &train.length, sizeof(train.length), MSG_WAITALL);
			recv(socket_fd, train.data, train.length, MSG_WAITALL);
			memcpy(token, train.data, train.length);
			break;
		}
		printf("请选择注册或登录(输入数字即可)：1.注册\t2.登录\n");
		int res = scanf("%d", &opt);
		getchar(); // 读回车
		if (res == EOF)
		{
			train.length = 0;
			send(socket_fd, &train, sizeof(train.length) + train.length, MSG_NOSIGNAL);
			close(socket_fd);
			exit(0);
		}
	}

	// 展示指令菜单
	printf("**********菜单**********\n");
	printf("1.cd:进入网盘对应目录\n"
		   "2.ls:列出网盘相应目录文件\n"
		   "3.puts:上传本地文件到网盘\n"
		   "4.gets:下载网盘文件到本地\n"
		   "5.remove:删除网盘文件\n"
		   "6.pwd:显示网盘当前路径\n"
		   "7.ctrl+d:退出网盘\n");

	// 指令
	char buf[1024] = {0};
	fd_set rdset;
	while (1)
	{
		FD_ZERO(&rdset);
		FD_SET(socket_fd, &rdset);
		FD_SET(STDIN_FILENO, &rdset);
		select(1024, &rdset, NULL, NULL, NULL);
		if (FD_ISSET(STDIN_FILENO, &rdset)) // 监听用户输入
		{
			bzero(buf, sizeof(buf));
			ssize_t ret_read = read(STDIN_FILENO, buf, sizeof(buf));
			if (ret_read == 0) // 用户通过Ctrl+d退出时
			{
				bzero(&train, sizeof(train));
				train.length = 0;
				send(socket_fd, &train, sizeof(train.length) + train.length, MSG_NOSIGNAL);
				NETDISK_LOG_INFO_1(socket_fd, "用户主动退出", serverAddr);
				printf("用户主动退出！\n");
				break;
			}
			int order_len = strlen(buf);
			buf[order_len - 1] = '\0';

			handle(buf, socket_fd, username, token, &serverAddr); // handle.c
		}
		// 监听到服务端消息
		if (FD_ISSET(socket_fd, &rdset))
		{
			bzero(buf, sizeof(buf));
			ssize_t res_read2 = read(socket_fd, buf, sizeof(buf));
			ERROR_CHECK(res_read2, -1, "read");
			if (res_read2 == 0)
			{
				NETDISK_LOG_INFO_1(socket_fd, "服务端断开连接", serverAddr);
				printf("与服务端断开连接！\n");
				break;
			}
		}
	}
	close(socket_fd);
	return 0;
}